home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-10-12 | 45.5 KB | 1,379 lines |
-
-
- GenGui V2.1
- ===========
-
- ©1994-95 by Matthias Meixner
-
- Read the README file for the legal issues
-
-
- This package is for layout and creation of graphical user interfaces (GUI).
- Unlike some other programs like Gadtools, you do not draw your GUI just like
- in a paint-program, but you describe the GUI in a kind of description
- language. From this description GenGui generates a C-headerfile, wich
- containes the description data in a form that is needed by the routines
- which must be linked to your program and which do the real work on runtime.
-
- For the legal issues read the "readme"-file.
-
-
- 1. Preface
- ==========
-
- From version 36 of the Amiga operating system on it is possible to select
- the font that should be used. Since there are now several new display-
- resolutions it is highly recommended, that applications should be able to
- use higher resolutions and therefore it is required, that programs can adapt
- to a variable windowsize.
- OK, lets face the current situation. There are half a dozen different
- systems out there, that all allow to create font-sensitive and resizeable
- GUIs. Most of them come with a shared library, that implemets its own
- gadgets, and they are all about 100kBytes in size. Since there is no
- standard for these tools yet, every programmer uses his preferred generator
- and every program uses another shared library. But what's the use of shared-
- libraries, if every program uses another one? If you have got three programs
- running, that all use a different library, then the libraries allocate
- already 300kBytes just for three layout-engines and for many unused button-
- types, each implementing their own version of the same types of buttons.
- Therefore I wrote Gengui. It uses GadTools-gadgets, which already come with
- the operating system and implements a layout-enging for these gadgets. It
- does not use a shared-library, but comes as a quite small link-library.
-
-
- 2. The basic idea:
- ==================
-
- The description of the Gui is box oriented. Every box affects the size
- and position of the objects inside the box. A box has an orientation, which
- determines the positions of the objects in a box, in a vertical box the
- first object is on top and all other objects are below this one, in a
- horizontal box, the first one is on the most left side. Within a box every
- object can have a relative size, a size absolut in characters or a size
- absolut in pixels or a mixture of the last two. This object can be a new box,
- a gadget or a custom "gadget". This allows an easy generation of resizeable
- GUI's.
-
- Maybe you should get an example now:
-
- Imagine you want to have a GUI, which looks like that:
-
-
- +-------------------------+
- | |
- | +-----+ +-----+ +-----+ |
- | |Text1| |Text2| |Text3| |
- | +-----+ +-----+ +-----+ |
- | |
- | |
- | |
- +-------------------------+
-
- The description would look like this:
-
- PROJECTNAME Project1 // This is the name, which will be used
- // in the generated source
-
- HBOX // horizontal box
- VREL 1 // the box has relative height
- HREL 1 // and relative width
- BUTTON // We want to generate a button
- STDLINE 1 // with a height of one line plus spacing
- HREL 1 // and relative width
- TEXT "Text1" // "Text1" should be written in it
- ID 1 // and maybe we want to identify it later
- END
- BUTTON
- STDLINE 1
- HREL 1
- TEXT "Text2"
- ID 2
- END
- BUTTON
- STDLINE 1
- HREL 1
- TEXT "Text3"
- ID 3
- END
- END
-
- This would describe a GUI with three gadgets, each has (including an adequate
- spacing) one third of the width of the window, and a height of one line.
-
- Gengui offers some reasonable defaultvalues for the different types of
- objects, which significantly reduce the size of the description:
-
-
- PROJECTNAME Project1
- HBOX
- BUTTON
- TEXT "Text1"
- ID 1
- END
- BUTTON
- TEXT "Text2"
- ID 2
- END
- BUTTON
- TEXT "Text3"
- ID 3
- END
- END
-
-
- Maybe you want the first button to be double as wide as the other two
- buttons:
-
-
- PROJECTNAME Project1
- HBOX
- BUTTON
- HREL 2 // now this button gets 2 parts of the width of this box
- TEXT "Text1"
- ID 1
- END
- BUTTON // whereas this button gets only one part,
- TEXT "Text2"
- ID 2
- END
- BUTTON // and this one too
- TEXT "Text3"
- ID 3
- END
- END
-
-
-
- Now lets think of something like that:
-
- +-----------------+
- | |
- | +-------------+ |
- | | | |
- | +-------------+ |
- | |
- | +--------+ |
- | | | |
- | +--------+ |
- | |
- | +---+ |
- | | | |
- | +---+ |
- | |
- +-----------------+
-
- The first button has three times the size and the second one two times the
- size of the last button.
-
-
- PROJECTNAME Project1
- VBOX // Now one button is above the other !
- BUTTON
- HREL 3 // Three thimes the size
- TEXT "Text1"
- ID 1
- END
- BUTTON
- HREL 2 // two times the size of the last button.
- TEXT "Text2"
- ID 2
- END
- BUTTON
- TEXT "Text3"
- ID 3
- END
- END
-
-
-
- And now a last example for this topic:
-
- +---------------+
- | |
- | +------+ |
- | | | |
- | +------+ |
- | |
- | +--+ +------+ |
- | | | | | |
- | | | | | |
- | | | | | |
- | | | | | |
- | +--+ +------+ |
- | |
- +---------------+
-
- PROJECTNAME Pro2
- HBOX
-
- VBOX // left box
- HREL 1
-
- VBOX // this creates the empty place in the top left corner
- END
-
- BUTTON
- VREL2
- END
- END
-
- VBOX // right box
- HREL 2 // of double width
-
- BUTTON
- VREL 1
- END
-
- BUTTON
- VREL 2
- END
- END
-
- END
-
-
- 3. Installation
- ===============
-
- Installation is quite easy:
-
- copy gengui.h to your include: directory or you will have to add the path
- where it can be found to your include-path.
-
-
- 4. The description language
- ===========================
-
- These are the keywords of the description languange. It does not distinguish
- between lower- and uppercase. Some keywords have more than one name, since
- i could not decide wich one would be more easy to remember :). These other
- names can be found in the brackets ().
-
- Every command must be on a separate line, comments begin with '//' and mark
- the rest of the line as comment.
-
- #c_source
- #end_source
-
- Everything between these two lines will be directly included in the
- generated output. These keywords must begin on the first column !
-
-
- These are the commands that are used to describe the objects of the GUI:
-
- BACKFILL Hook: Install a Backfill Hook, that is used for rendering
- the background of this box.
-
- BAR
- BAR : Insert a bar between two objects. The direction depends on
- the containing object. If this is a VBOX, then a horizontal
- bar will be generated, otherwise a vertical bar.
-
- BUTTON
- BUTTON : Normal button, default size HREL 1, STDLINE 1,
- MINHCHAR strlen(Text), MINHPIX 4
-
-
- CHECKBOX
- CHECKBOX : Checkbox, default size HCAR 2, VCHAR 1
-
-
- CUSTOM
- CUSTOM : Custom Gadget, default size HREL 1, VREL 1,
- Read also the chapter about custom gadgets !
-
- CYCLE
- CYCLE : Cycle-gadget, default size HREL 1, STDLINE 1
- MINHCHAR max(strlen(Texts in the Cyclegadget)),
- MINHPIX 24
-
-
- FRAME
- FRAME RAISED|RECESSED
- : Draw a frame around this Box (VBOX or HBOX).
- It is raised (FRAME RAISED) or recessed (FRAME RECESSED).
-
- GFXBUTTON : Graphical button. It supports two highlight-methods:
- complement and highlight-image. The images are selected within
- this block with the "IMAGE" command. If there is one such
- command, then complement is used, if there are two of them,
- then the second one is used for highlighting.
-
- You can adjust the alignment within its space with the
- following flags:
-
- Horizontal alignment: GG_Left,GG_HCentered,GG_Right
- Vertical alignment: GG_Top,GG_VCentered,GG_Bottom
-
- default: GG_Left,GG_Top
-
- You can switch off highlighting by the GG_NoHighlight-flag.
-
- The size of the active region of the button, i.e. the region,
- that reacts to mouse-clicks, is determined by the size of
- the first image, unless you use the GG_FullSize flag, which
- tells gengui, that the whole allocated space should be
- active.
-
- NOTE: you need to select a suitable activation for this
- gadget, e.g. with:
-
- ACTIVATION GACT_RELVERIFY
-
- GFXBUTTON now supports to change the GFLG_SELECTED flag
- during runtime with GG_SetGadgetAttrs(). The tag to
- do that is GA_Disabled and it must be the first tag in the
- taglist.
-
-
- HBOX
- HBOX : horizontal box, default size: HREL 1, VREL 1
-
- INTEGER
- INTEGER : Integer-gadget, default size HREL 1, STDLINE 1
-
- LISTVIEW
- LISTVIEW : default size HREL 1, VREL 1
-
- MX
- MX : MX-gadget, default size HREL 1, VREL 1,
- MINVCHAR # of entries, MINVPIX 6
-
- NUMBER
- NUMBER : Number-gadget, default size HREL 1, STDLINE 1
-
- PALETTE
- PALETTE : Palette-gadget, default size HREL 1, VREL 1
-
- PLAINTEXT
- PLAINTEXT: Formatted Text, default size HREL 1, STDLINE 1.
- MINHPIX and MINVPIX are set according to the size of the
- text as default.
- Plaintext supports the following format descriptions:
-
- \n : Newline
- %% : '%'
-
- %Cx : Set foreground color to x
- (e.g. %C1 : set color to 1)
- %cx : Set background color to x
-
- %B : Bold on
- %b : Bold off
- %I : Italics on
- %i : Italics off
- %N : Normal style (Bold,Italics,Underlined off)
- %U : Underlined on
- %u : Underlined off
-
- You can adjust the alignment within its space with the following
- flags:
-
- Horizontal alignment: GG_Left,GG_HCentered,GG_Right
- Vertical alignment: GG_Top,GG_VCentered,GG_Bottom
-
- default: GG_Left,GG_Top
-
- Unlike TEXT this is not a gadtools gadget, but allows easier
- formatting of text, since it allows texts, that use more
- than one color, style or that span more than one line.
-
- See also GfxPrint();
-
- SCROLLER
- SCROLLER : Scroller, default size HREL 1, VREL 1
-
- SLIDER
- SLIDER : Slider, default size HREL 1, VREL 1
-
- STRING
- STRING : String-gadget, default size HREL 1, STDLINE 1
-
- TEXT
- TEXT : Text-gadget, default size HREL 1, STDLINE 1
- See also PLAINTEXT
-
- VBOX
- VBOX : vertical box, default size: HREL 1, VREL 1
-
-
- Each of these commads defines a block, which must be terminated by "END"
-
-
-
- Commands specifying the size of the objects:
-
- HCHAR (XCHAR)
- HCHAR chars : Absolute width of 'chars' characters
-
- HPIX (XPIX)
- HPIX pixel : Absolute width of 'pixel' pixels
-
- HREL (XREL)
- HREL size : Relative width
-
- STDCOL
- STDCOL chars : Absolute width of 'chars' characters plus 4 pixels space
-
- STDLINE
- STDLINE chars : Absolute height of 'chars' characters plus 4 pixels space
-
- VCHAR (YCHAR)
- VCHAR chars : Absolute height of 'chars' characters
-
- VPIX (YPIX)
- VPIX pixel : Absolute height of 'pixel' pixels
-
- VREL (YREL)
- VREL size : Relative height
-
- XSPACE
- XSPACE xs : Set the amount of horizontal space between gadgets to
- xs pixels, defaults to INTERWIDTH
- (only allowed within HBOX/VBOX)
- YSPACE
- YSPACE ys : Set the amount of vertical space between gadgets to
- ys pixels, defaults to INTERHEIGHT
- (only allowed within HBOX/VBOX)
-
-
- Commands specifying the minimal size for relative objects (box or gadget):
-
- MINHCHAR (MINXCHAR)
- MINHCHAR chars : Minimal width of 'chars' characters
-
- MINHPIX (MINXPIX)
- MINHPIX pixel : Minimal width of 'pixel' pixels
-
- MINSTDCOL
- MINSTDCOL chars : Minimal width of 'chars' characters plus 4 pixels space
-
- MINSTDLINE
- MINSTDLINE chars : Minimal height of 'chars' characters plus 4 pixels space
-
- MINVCHAR (MINYCHAR)
- MINVCHAR chars : Minimal height of 'chars' characters
-
- MINVPIX (MINYPIX)
- MINVPIX pixel : Minimal height of 'pixel' pixels
-
-
-
- Commands that are used to reserve free space next to an object
-
- BOTTOMCHARSPACE
- BOTTOMCHARSPACE char: reserves free space in the bottom of the object,
- that is 'char' characters high
- LEFTCHARSPACE
- LEFTCHARSPACE char : reserves free space left to the object, that is
- 'char' characters wide
- RIGHTCHARSPACE
- RIGHTCHARSPACE char : reserves free space right to the object, that is
- 'char' characters wide
- TOPCHARSPACE
- TOPCHARSPACE char : reserves free space in the top of the object,
- that is 'char' characters high
-
-
- BOTTOMPIXSPACE
- BOTTOMPIXSPACE pix: reserves free space in the bottom of the object,
- that is 'pix' pixels high
- LEFTPIXSPACE
- LEFTPIXSPACE pix : reserves free space left to the object, that is
- 'pix' pixels wide
- RIGHTPIXSPACE
- RIGHTPIXSPACE pix : reserves free space right to the object, that is
- 'pix' pixels wide
- TOPPIXSPACE
- TOPPIXSPACE pix : reserves free space in the top of the object,
- that is 'pix' pixels high
-
-
- BOTTOMSTDSPACE
- BOTTOMSTDSPACE char: reserves free space in the bottom of the object,
- that is 'char' characters plus 4 pixels high
- LEFTSTDSPACE
- LEFTSTDSPACE char : reserves free space left to the object, that is
- 'char' characters plus 4 pixels wide
- RIGHTSTDSPACE
- RIGHTSTDSPACE char : reserves free space right to the object, that is
- 'char' characters plus 4 pixels wide
- TOPSTDSPACE
- TOPSTDSPACE char : reserves free space in the top of the object,
- that is 'char' characters plus 4 pixels high
-
-
- These commands specify the minimal width/height for objects with relative
- width/height. It does not affect the relative sizes of different objects.
- Thus if you have two objects within one box, each having the same relative
- width and one of these has a minimal width of 5 chars and the other one
- of 6 chars, then the minimal width of the first one will also be 6 chars,
- since the relative size says, that the two objects have always the same
- width.
- The default values used by Gengui for the minimal sizes are often sufficient
- enougth, therefore you will not need to use these commands too often.
- (At least I hope so :-) )
-
-
- Commands for the description of gadget-specific data:
-
- ACTIVATION
- ACTIVATION flg: Set the activation-flags for GFXBUTTONS (GACT_...).
- See also intuition/intuition.h
-
- CUSTOM
- CUSTOM func : Set the custom function for custom-gadgets.
- NOTE: this is only valid within a custom-object and since
- it is written the same way as the CUSTOM-object
- the meaning of CUSTOM only depends on the context.
-
- FLAGS
- FLAGS flagset : Set the flags of the gadget (-> ng_Flags)
- NOTE: it is possible spread the flags to more than one
- FLAGS command e.g.:
-
- FLAGS a|b
-
- would have the same effect as
-
- FLAGS a
- FLAGS b
-
-
- HOOK
- HOOK function : Set a hook function that is called, when the gadget sends
- a message. See also the chapter on hook-functions.
-
- ID
- ID [label=]id : Set the ID of the gadget (-> ng_GadgetID)
- NOTE: id must not contain any whitespace characters !
- The value of the ID must be >=0. If you supply a label,
- then gengui will generate the following define:
-
- #define label id
-
- Furthermore it will use the label for the generation of
- the Names, that are used to access the Gadgets.
-
-
- IMAGE
- IMAGE image : This sets the image-data for GFXBUTTONs. "image" must
- point to a "struct Image" variable. You can generate this
- data using IconEdit when you have set "SRC" in the
- tooltypes of IconEdit. Then you will find "Save as C..."
- in the projects menu. Since IconEdit generates some
- additional information for the icons, you will need to
- delete this information from the generated sourcecode.
- You may define up to two images for every GFXBUTTON.
- If there are two of them, then the second one is used for
- highlighting.
-
- LABELS
- LABELS label1 [,label2 ...]:
- Generates everything required for labels in MX-BUTTONS
- and CYCLE-BUTTONS. These are the string arrays and the
- suitable tags for the taglists.
-
- TAGS
- TAGS tags : Set the tags for a gadget. You need not set TAG_DONE,
- since this is automatically done. You may use more than
- one TAGS command per gadget, e.g.
-
- TAGS a,b
- TAGS c,d
-
- would have the same effect as
-
- TAGS a,b,c,d
-
- TEXT
- TEXT string : Set the text for the gadget (-> ng_GadgetText)
- If you specify more than one text, then all these texts
- are concatenated.
-
- TEXTATTR
- TEXTATTR textattr : Set ng_TextAttr. By default the standart font of the
- window is used for the gadgets.
-
-
- TEXTID
- TEXTID [label=]id: Text-id for the use with localized GUI's. Note that
- you also need to link with gengui_lnk_locale.o
- to activate the support for locale.library.
- Furthermore you need to define and initialize the
- variable 'Catalog' with the catalog, that should be
- used. If Catalog is NULL, or if there is no
- translation in the catalog, then gengui will use the
- non-translated texts, that were set with "TEXT".
-
- IMPORTANT: If you don't select a TEXTID, then "65535"
- will be used as ID. Therefore this ID
- must not occur in your catalog-file !
-
- If you supply a label, then gengui will generate the
- following define:
-
- #define label id
-
- See also examples/xarc_locale
-
-
- USER
- USER userdata : Set user data. You can access the user data via the
- macro GetUserData().
- NOTE: the field ng_UserData is required by GenGui itself,
- but therefore it has another field reserved for
- this purpose.
-
-
- General note: The parameters of all these commands may be preprocessor
- symbols, in fact they are just passed on to the generated
- source.
-
-
- 5. What's generated by GenGui
- =============================
- GenGui takes the descriptionfile and generates two headerfile. The first
- headerfile contains the full data of the descriptionfile and some required
- or useful defines. First it contains a struct WinInfo that has the name which
- was set using the command projectname. This struct is required for rendering
- the GUI to the window, therefore it is the most important structure in the
- headerfile. It allocates GadInfo structures, which store the information of
- the look of the GUI. To make these accessible for GG_SetLowlevelAttrs()
- Gengui generates defines which are used to supersede the generic names of
- the structure valiables. The names have the form:
-
- 'Projectname'_GadInfo_'GadgetID'
-
- 'GadgetID' is the ID, given by the 'ID' command or the label, if given.
-
- They identify the variables themselves. Therefore you will need to use the
- &-operator to get the address of them for use with GG_SetLowlevelAttrs().
-
- Furthermore an array of pointers to gadgets is allocated in the headerfile.
- The name of this array has the form:
-
- 'Projectname'_Gadgets
-
- This array contains the pointers to the gadgets which you require for e.g.
- setting new attributes of the gadgets via GG_SetGadgetAttrs(). But note,
- that these entries are only valid as long as the GUI is rendered to the
- window and that these entries change when the GUI is resized or changed in
- other ways. To know which entry in this array belongs to a certain gadget,
- GenGui generates a definition for every Gadget, which tells you which entry
- belongs to a certain gadget. The name of this definition has the form:
-
- 'Projectname'_'GadgetID'
-
- OK, let's have a simple example to illustrate, how you would use it. The
- second headerfile has the extension "_def.h" and contains only the structure
- definitions, the prototypes, the "extern" references and the #defines. It is
- useful if you want to access the GUI from another module.
-
- This could be a description of a GUI:
-
- #c_source
-
- #define ExampleButton 1 // I want to have a more telling name than a number
-
- #end_source
-
- Projectname Test
- VBOX
- BUTTON
- TEXT "Test"
- ID ExampleButton
- end
- end
-
- or which is equivalent:
-
-
- Projectname TEST
- VBOX
- BUTTON
- TEXT "Test"
- ID ExampleButton=1
- end
- end
-
-
- To render the GUI to the window you would use:
-
- RenderGui(window,&Test);
-
- And to change the attributes of the gadget you would use:
-
- GG_SetGadgetAttrs(Test_Gadgets[Test_ExampleButton],window,NULL, ... );
-
- Or for lowlevel changes:
- GG_SetLowlevelAttrs(&Test_GadInfo_ExampleButton, .... );
-
-
- For the handling of gadgets, there are some useful macros in gengui.h,
- which is automatically included in the generated headerfiles:
-
- GetGadget() generates the address of the selected gadget from the
- received IntuiMessage:
-
- struct Gadget *GetGadget(struct IntuiMessage *)
-
-
- GetInfo() calculates the address of the GadInfo structure from the
- address of the gadget.
-
- struct GadInfo *GetInfo(struct Gadget *)
-
-
- GetString() takes the address of a string-gadget and retrieves a pointer
- to the contents of the buffer.
-
- UBYTE *GetString(struct Gadget *)
-
-
- GetNumber() retrieves the value stored in a number-gadget.
-
- LONG GetNumber(struct Gadget *)
-
-
- GetUserData(): Since Gengui needs the field "UserData" for internal use, it
- reserves another field for this purpose, it generates a this
- macro GetUserData() that fullfills the purpose of accessing
- this field for userdata.
-
- ULONG GetUserData(struct Gadget *)
-
-
- For the handling of customgadgets you require some additional defines:
- First there are some "modes" defined, whose meaning is explained in the
- chapter for customgadgets.
-
- The other structures in the headerfile contain the actual data that
- describes the GUI. Since they are not important for the programmer their
- names consist of the projectname and an extension of some numbers and
- characters.
-
- If you want to know more of what can be found in the headerfile you should
- have a look at the generated source :).
-
-
- 6. Writing code using GenGui
- ============================
- The first thing you have to do is to write the file with the description of
- the GUI in the description-language, that was presented in chapter 2. The
- filename must have the extension .gui. The next step is to compile this
- description to a normal C-headerfile using GenGui:
- GenGui file.gui
-
- You will get two headerfiles: file.h and file_def.h
- "file.h" contains the data of the GUI and "file_def.h" contains all from
- "file.h" except for the data itself.
-
- There are two important aspects:
- - You must use Gui_GetIMsg() instead of GT_GetIMsg()!
- - You must use Gui_SetGadgetAttrs() instead of GT_SetGadgetAttrs()!
-
- The following example will show you how to use these GUI's within your own
- programs:
-
- #include "file.h" // include the headerfile that was generated by GenGui
-
- main()
- {
- struct IntuiMessage *msg;
- struct WIndow *win;
- int run=1;
-
- /*
-
- . Now open all required libraries and the window. "win" must point to
- . the newly opened window.
-
- */
-
- /* The Projectname of the GUI is TestPro */
-
- if(GG_RenderGui(win,&TestPro)) {/* do the cleanup, send an error msg .... */}
- /* GG_RenderGui returns 0 if successful, an error code on failure */
-
- while(run) {
- WaitPort(win->UserPort); // you may use Wait instead, if you like :)
-
- while(msg=GG_GetIMsg(win->UserPort)) {
- /* It is very important that you use this function instead of
- GetMsg or GT_GetIMsg(), since it does some additional
- actions !!! */
-
- switch(msg->Class) {
- case IDCMP_CLOSEWINDOW: run=0;break;
- case IDCMP_NEWSIZE: GG_ResizeGui(&TestPro); // do the resizing
- break;
- case IDCMP_REFRESHWINDOW:
- GG_BeginRefresh(&TestPro);
- GG_RefreshGui(&TestPro); // and the refresh
- GG_EndRefresh(&TestPro,TRUE);
- break;
- // ... and some more actions you need
- }
- GG_ReplyIMsg(msg);
- }
- }
-
- GG_FreeGui(&TestPro); // Free the gadgets
-
- /* close the window and free the sources etc. */
- }
-
- When opening the window you should consider that it must be large enough to
- have room for all gadgets. If the window is too small then the GUI will look
- quite messed up. You can determine the minimal required size with the
- GG_MinSize function, at least when the MIN-sizes are correctly set. Or you
- can use GG_SmartRenderGui, which takes care of the needed size and moves or
- resizes the window due to these requirements. It even substitutes the font
- used in the window by a smaller one, if required.
-
-
- 5. Hook functions
- =================
- For every gadget you may define a hook-function. This function is called
- whenever Intuition sends a message for this gadget. It receives the address
- of the Intuimessage as parameter and must return an int as result. If you
- return null then the Intuimessage is passed on to your main program, in the
- other case the Intuimessage is ignored and your program will not receive
- this message any more:
-
- int __stdargs HookFunction(struct IntuiMessage *msg)
- {
- int ignore=1; /* The IntuiMessage will not be passed on to the program */
-
-
- /* do some actions */
-
- return ignore;
- }
-
-
- 7. Custom gadgets
- =================
- Custom gadgets are a very powerful element for generating graphical user
- interfaces. They not only allow you to add gadgets other than gadtools
- gadgets, you can also use it to render information to the window, that is
- not really a gadget, for example some borders or texts, which should
- be resizeable. And a special thing which you can create using customgadgets
- are multiplexed user interfaces. "What's that?", you may ask. OK, I'll give
- you an idea, what you can achieve by this. Imagine that there is not enough
- room in the window to place all gadgets in it. Then you could have e.g. a
- cyclegadget with which you can select the group of gadgets you want to
- be visible in the window.
- First at all every customgadget requires a function that handles the
- creation of the "gadget". This function gets 7 arguments, the first one is
- a pointer to a WinInfo structure, the second one is a pointer to a NewGadget
- structure which was filled with all needed data (only MODE_NEW,MODE_RESIZE
- and MODE_REFRESH). The third one is a pointer to a GadInfo and the last
- four parameters describe the position and the width/height of the area of
- gadget.
- NOTE: The area of the gadget also contains the spacing around the gadget.
- The (suggested) dimensions of the gadget itself can be found in the
- newgadget structure.
-
- This function is called in several cases. It is not only called when the
- gadget should be created, but also when it should be removed. There are
- 6 Modes, which are marked in 'Mode' field of the WinInfo structure.
- The Modes are:
-
- GG_MODE_NEW: A new gadget should be created. If you create gadgets you
- should add them to the GList 'Gadgets' in the WinInfo
- structure and fill 'Prev' in the same structure with the
- pointer to the last gadget.
-
- GG_MODE_RESIZE: The gadget should be resized. You must not use
- GT_SetGadgetAttrs() to change the state of gadtools gadgets,
- since during the GG_MODE_RESIZE call the gadgets are not
- bound to any window and GG_SetGadgetAttrs() would not work
- at this point, but you might use GG_SetLowlevelAttrs().
-
- GG_MODE_REFRESH: Redraw the gadget. You need not redraw system-gadgets, since
- RefreshGList() is called internally.
-
- GG_MODE_FREE: Free the gadget and delete all stored contents
-
- GG_MODE_STOP: Delete the gadget, but keep the contents, that were stored
- by GG_MODE_BACKUP.
-
- GG_MODE_BACKUP: Store the complete information of the gadget e.g. if the
- gadget is disabled and the selection-state. You may store
- that information in the Code field of the delivered GadInfo
- structure and the information if it is disabled can be
- stored using the flag GG_FLAG_DISABLED in 'dim.Flags' of
- this structure. You must not change any other bits in this
- field.
-
- GG_MODE_RESTORE: Restore the information that was stored with GG_MODE_BACKUP.
-
-
- If you just want to draw some lines, you should ignore the latter three
- cases that are only important for the handling of gadgets or 'SubGui's. In
- these cases the contents of the NewGadget structure are not valid, however
- you will get a pointer to such a structure to avoid enforcer-hits.
- You can also use the field Render in the WinInfo structure to determine if
- you have draw your lines. It is set to 1 if drawing is needed and to 0 if
- not.
-
- You must return 0 if everything was OK and any value !=0 if an error
- occurred.
-
- If you want to draw some lines and render another GUI in this area you can
- use "SubGuis". Therefore you must describe a complete GUI just like before
- and render this GUI with GG_SubGui() to the window. This function takes the
- same parameters as RenderGui() plus four additional parameters which
- describe the position and the dimensions of the GUI. You must call this
- every time your customfunction is called. This function returns 0 on success
- and a value !=0 if an error occurred. In this case your function must
- also return a value !=0 to tell that there was an error.
- There is another thing that is possible using 'SubGuis', that are
- multiplexed user-interfaces. You might have several groups of gadgets that
- are rendered to the same place in the window and e.g. a global variable
- decides which of these groups is displayed in the window. Note that you must
- remove the complete GUI from the window first, if you want to switch the
- groups, but you cannot use FreeGui(), since this would lose the complete
- information that is stored in the GUI. StopGui() exists for this case. It
- stores this information and removes the GUI after this. The next time you
- call RenderGUI this information is restored. StopGUI() can also be used
- if you want to keep informations although you want to close the window,
- because you might reopen it later. See also the example for multiplexed
- interfaces.
-
-
- 8. The functions in the runtime-library "gengui_lnk.o"
- ======================================================
-
- GG_BeginRefresh:
-
- void GG_BeginRefresh(struct WinInfo *winfo)
-
- Invokes the intuition.library/BeginRefresh() function in a manner
- friendly to the gengui toolkit. This function call permits the
- gadgets to refresh themselves at the correct time and restricts
- rendering to the damaged regions that need refresh.
- Call GT_EndRefresh() function when done.
-
- NOTE:
-
- The nature of GadTools precludes the use of the IDCMP flag
- WFLG_NOCAREREFRESH. You must handle IDCMP_REFRESHWINDOW events
- in at least the minimal way, namely:
-
-
- case IDCMP_REFRESHWINDOW:
- GG_BeginRefresh(wininfo);
- GG_EndRefresh(wininfo, TRUE);
- break;
-
- Normally you would use:
-
- case IDCMP_REFRESHWINDOW:
- GG_BeginRefresh(&Project);
- GG_RefreshGui(&Project);
- GG_EndRefresh(&Project, TRUE);
- break;
-
-
-
- GG_BeginResizeGui:
-
- void GG_BeginResizeGui(struct WinInfo *winfo)
-
- You can use this function to speed up the process of resizing the GUI.
- Therefore you have to use IDCMP_SIZEVERIFY, which signals your program,
- that the user wants to resize the GUI. If you call GG_BeginResizeGui,
- when this happens, all gadgets are detached from the window and intuition
- does no refresh on these gadgets, which would be useless anyways, since
- the GUI is refreshed after it has been resized. But note, you really
- should know, that if you don't handle this message immediately, you may
- get a deadlock of your system. Therefore don't use IDCMP_SIZEVERIFY if
- you are not sure about the side-effects of switching on this
- message-type. It's probably better to have a slightly slower program,
- than a buggy program.
-
-
- GG_ClearWindow:
-
- void GG_ClearWindow(struct Window *)
-
- Removes all contents from the window, erases the inner of the window
- with the EraseRect() and refreshes the windowborders.
-
-
- GG_EndRefresh:
-
- void GG_EndRefresh(struct WinInfo *winfo, BOOL complete)
-
- Invokes the intuition.library/EndRefresh() function in a manner
- friendly to the gengui toolkit. This function call permits the
- gadgets to refresh themselves at the correct time and restricts
- rendering to the damaged regions that need refresh.
- Call this function when you have used GG_BeginRefresh()
-
-
- GG_FreeGui:
-
- void GG_FreeGui(struct WinInfo *winfo)
-
- GG_FreeGui removes the gadgets from the window. It is save to call this
- functions for already freed GUIs.
-
-
- GG_GetIMsg:
-
- struct IntuiMessage *GG_GetIMsg(struct MsgPort *)
-
- You must call this function instead of GT_GetIMsg() or GetMsg().
- It returns a pointer to an IntuiMessage, if there is a message of
- interest for the program, otherwise it returns NULL. This is for example
- the case if you have a hook-function seleced for a gadget which returns a
- value !=0 to indicate that the message may be ignored.
-
-
- GG_GfxPrint:
-
- void GG_GfxPrint(struct RastPort *rast,char *text,int left,int top);
-
- This function is used to format and print a text to a RastPort.
- The following format-specifiers are supported:
-
- \n : Newline: the next character is printed at the start
- of the next line.
- %% : '%'
-
- %Cx : Set foreground color to x
- (e.g. %C1 : set color to 1)
- %cx : Set background color to x
-
- %B : Bold on
- %b : Bold off
- %I : Italics on
- %i : Italics off
- %N : Normal style (Bold,Italics,Underlined off)
- %U : Underlined on
- %u : Underlined off
-
- Parameters:
- rast : Pointer to your RastPort
- text : A pointer to your textstring
- left,top : Left, top corner of the textblock
-
-
- GG_GfxPrintSize:
-
- void GG_GfxPrintSize(struct RastPort *rast,char *text,struct TextSize *size);
-
- This function is used to calculate the width and height a text
- would occupy when printed with GG_GfxPrint().
-
-
- Parameters:
- rast : Pointer to your RastPort
- text : A pointer to your textstring
-
- size : A pointer to the struct, in which the result will
- be stored.
-
-
- GG_MinSize:
-
- void GG_MinSize(struct Window *win, struct WinInfo *gui,
- struct GG_ObjectSize *size);
-
- GG_MinSize calculates the minimal size for the window win, such that
- the gui will fit within this window. The result is written to 'size',
- which must point to some valid memory-position. This size does not cover
- any bordersizes of the window, these must be added to the calculated
- sizes.
-
-
- GG_MinSize:
-
- void GG_MinSizeFont(struct TextFont *font, struct WinInfo *gui,
- struct GG_ObjectSize *size);
-
- GG_MinSizeFont calculates the minimal size for the font 'font', such that
- the gui will fit within window of this (inner) size. The result is
- written to 'size', which must point to some valid memory-position.
- This size does not cover any bordersizes of the window. Therefore
- it would be suitable for opening a window with WA_InnerWidth and
- WA_InnerHeight.
-
-
- GG_RefreshGui:
-
- int GG_RefreshGui(struct WinInfo *winfo)
-
- This function is used to refresh the gadgets within the window.
- It is only important if you are using SimpleRefresh, since only then it
- is your job to refresh the window. If you are using SmartRefresh windows
- then it should not be required since the system does that job for you.
- It returns 0 if everything was OK.
-
-
- GG_RenderGui:
-
- int GG_RenderGui(struct Window *win, struct WinInfo *winfo)
-
- GG_RenderGui draws the gadgets to the window. You must supply the pointer
- to the window and the pointer to the WinInfo structure of your GUI.
- This one can be obtained by using the & operator on the name that was
- selected using "PROJECTNAME" in the descriptionfile.
- It returns 0 if everything was OK.
-
-
- GG_ResizeGui:
-
- int GG_ResizeGui(struct WinInfo *winfo)
-
- This function is used to adapt the GUI to the new size when a window
- has been resized. You must call this function every time you receive
- a IDCMP_NEWSIZE message.
- It returns 0 if everything was OK.
- You can speed up the resizing-process by using GG_BeginResizeGui.
-
-
- GG_SetGadgetAttrs / GG_SetGadgetAttrsA:
-
- BOOL GG_SetGadgetAttrsA(struct Gadget *, struct Window *,
- struct Requester *, struct TagItem *)
-
- BOOL GG_SetGadgetAttrs(struct Gadget *, struct Window *,
- struct Requester *, Tag, ...)
-
-
- This is a replacemet for the function GT_SetGadgetAttrs of
- gadtools.library. You must call this function instead of that of gadtools,
- since Gengui needs to keep track of the information stored in the gadgets.
- NOTE: Whereas the gadtools function returns VOID this one returns if it
- was successful to modify the attributes. If there is not enough
- memory it returns 0 to indicate that there was an error and the
- attributes are not changed.
-
-
- GG_SetLowlevelAttrs / GG_SetLowlevelAttrsA:
-
- BOOL GG_SetLowlevelAttrsA(struct GadInfo *, struct TagItem *)
-
- BOOL GG_SetLowlevelAttrs(struct GadInfo *, Tag, ...)
-
- Whereas the GG_SetAttrs function cannot be used, as long as the
- GUI is not rendered to a window, and cannot be used for changing tags,
- that cannot be changed as long as Gadgets are rendered to a window,
- e.g. the depth of a palette-gadget, these functions can do this magic
- thing. If the GUI is already rendered to a window, you must call
- GG_ResizeGui after this function, to make these changes take effect.
- GG_ResizeGui removes and recreates all gadgets and this allows to
- change really all tags.
-
-
- GG_SmartRenderGui:
-
- int GG_SmartRenderGui(struct Window *win, struct WinInfo *winfo,
- struct TextFont **font)
-
- GG_SmartRenderGui determines the minimum size of the GUI and adjusts the
- window according to this information. Therefore it may resize and move
- the window and if this is not sufficient, it will switch to another font.
- Therefore you must call it with a pointer to a pointer to a font.
- If this pointer is a nullpointer, then it will open the topaz 80 font,
- in the other case it will use the delivered font as a fall-back font.
- It is up to you to close this font, when your program exits. If the GUI
- would not fit within the window, although it already uses the fall-back-
- font, it ignores that and the display might look messed up, but that's
- probably better, than not being able to display anything at all,
- since the user then really has no chance to use the program.
-
- GG_SmartRenderGui draws the gadgets to the window. You must supply the
- pointer to the window and the pointer to the WinInfo structure of your
- GUI. This one can be obtained by using the & operator on the name that
- was selected using "PROJECTNAME" in the descriptionfile.
- It returns 0 if everything was OK.
-
-
- Input:
- win: Pointer to an open Window
- winfo: Pointer to your GUI, You can obtain this pointer
- by using the & operator on the name, you have given
- for PROJECTNAME in the descriptionfile
- font: Pointer to an pointer to an fall-back-font or to a
- NULL-pointer.
-
-
- Result: 0 if everything was OK
-
-
- Example:
-
- struct TextFont *font=NULL;
-
-
- ...
-
- /* Open your window */
-
-
-
- if(GG_SmartRenderGui(win,&Gui,&font)) {
-
- /* failed */
-
- CloseWindow(win);
- if(font) CloseFont(font);
-
- /* additional error-handling */
- }
-
-
-
- ... /* Your code goes here */
-
- CloseWindow(win)
- if(font) CloseFont(font); /* you must not close it, as long as
- the window stays open, since it will be
- uses as long as this window exists */
-
-
-
- Notes:
- - If you call it with your own fall-back font, that was obtained by
- OpenDiskFont, you must call CloseDiskFont instead of CloseFont.
-
- - The fall-back font should definitely be smaller than the default-font,
-
-
- GG_StopGui:
-
- void GG_StopGui(struct WinInfo *winfo)
-
- GG_StopGui() stores the information of the gadgets and removes them after
- this from the window. GG_RenderGui() will recognize if the information was
- stored and will restore them if this was the case.
-
-
- GG_SubGui:
-
- int GG_SubGui(struct WinInfo *parent, struct WinInfo *winfo,
- int left,int top,int width, int height)
-
- GG_SubGui allows to draw GUIs within another GUI. You must not use this
- function for other purposes. It is not possible to render a GUI only
- with this function. You must use GG_RenderGui() for this, since it
- allocates some additional resources wich are also required by GG_SubGui
- and must be already allocated when GG_SubGui is called.
-
-
-
- MACROS:
- ======
-
- GetString:
-
- UBYTE * GetString(struct Gadget *)
-
- This macro returns a pointer to the contents of a string-gadget if passed
- a pointer to the string-gadget.
-
-
- GetNumber:
-
- LONG GetNumber(struct Gadget *)
-
- This macro returns the contents of a integer-gadget if passed
- a pointer to the integer-gadget.
-
-
- GetInfo:
-
- struct GadInfo * GetInfo(struct Gadget *)
-
- This macro returns a pointer to the correlated GadInfo structure of a
- given gadget.
-
-
- GetUserData:
-
- ULONG GetUserData(struct Gadget *)
-
- This macro returns a the userdata of the given gadget.
-
- NOTE: You cannot use the udserdata-field of gadtools gadgets, since
- this field is required by the gengui link-library for internal use.
-
-
- GetGadget:
-
- struct Gadget * GetGadget(struct IntuiMessage *)
-
- This macro calculates the address of the gadget in an intuimessage
- of the type IDCMP_GADGETUP or IDCMP_GADGETDOWN
-
-
- 9. Compiling
- ============
-
- You need to compile gengui_lnk.c in the Gui_lib directory and link this to
- your program. Of course you need not recompile it every time. Just compile
- it with your favourite C-compiler and then link gengui_lnk.o to your program.
- If you are using SAS-C, then you can use the already compiled module in this
- directory.
-
-
- 10. What's new
- =============
-
- Version 2.1:
-
- There is now support for easy reserving space aroung objects, that is
- required for e.g. the texts of gadgets. (Till version 2.0 you had to
- reserve it via empty boxes.)
-
-
- Previous versions did not support BeginRefresh and EndRefresh, this
- caused a slowdown of the refresh and of scrolling in the window.
- Now there are GG_BeginRefresh() and GG_EndRefresh(). These clean up
- the damage-list of the window and reduce the rendering of the refresh
- to the damaged regions and therefore speed up the refresh.
-
- Version 2.0:
-
- GenGui has some additional capabilities for designing GUI's. There are:
-
- - frames
- - bars
- - graphical buttons
- - formatted texts
- - backgound patterns
-
- Furthermore GenGui is now able to determine the minimum size of the window
- the GUI should be rendered to. Therefore there is a new set of commands
- for the description language, to determine the minimum size for boxes or
- gadgets with relative size. The user is supported by a quite complex
- default-mechanism, so that he need not give any information in most cases.
-
-
- Then I have cleaned up the names of the interface for gengui. But don't
- panic, if you define GG_OLDSTYLE you will get the old names for
- compatibility reasons.
-
- NOTE: It is not possible just to link with the new link-library, you have
- also to recompile the GUI-description with the new gengui, but that
- shouldn't be a problem.
-
- NOTE2: You should not use Gui_GetIMsg any more, which internally replies
- the Intuimessage, since this could mess up multi-selections of menus.
- Instead you should use GG_GetIMsg() and GG_ReplyMsg().
-
-
- 11. Credits
- ===========
-
- Thanks to all who have sent me bug-reports and / or suggestions for
- improvements of this tool.
-
-
-